home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / pc / Open Me for REALbasic 3 / REALbasic 3.2 / Goodies / 3rd Party Demos / 3rd Party Plugins / Misc / PEVocoder 1.0 (PPC) / PEVocodePlugin Source Code / aiff.cp next >
Encoding:
Text File  |  2000-11-22  |  4.7 KB  |  164 lines

  1. /******************************************************************************
  2.  * $Id: aiff.c,v 1.2 1998/09/13 00:21:18 emanuel Exp $
  3.  * Copyright (C) 1998 Emanuel Borsboom <emanuel@zerius.com>
  4.  * Permission is granted to make any use of this code subject to the condition
  5.  * that all copies contain this notice and an indication of what has been
  6.  * changed.
  7.  *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. /*#include <sys/errno.h>*/
  12. #include <errno.h>
  13. #include "config.h"
  14. #include "error.h"
  15. #include "aiff.h"
  16.  
  17. WAVE_FILE *aiff_open(FILE *fp, WAVE_INFO *info)
  18. {
  19.   char file_id[5], form_type[5];
  20.   INT file_data_size, file_position;
  21.   WAVE_FILE *file;
  22.   BOOL is_aifc;
  23.  
  24.   /* common chunk */
  25.   BOOL got_common_chunk = FALSE;
  26.   SHORT num_channels = 0, sample_size = 0;
  27.   char compression_type[5];
  28.   UINT num_sample_frames = 0;
  29.   REAL sample_rate = 0;
  30.  
  31.   /* sound data chunk */
  32.   UINT offset, block_size;
  33.   BOOL got_sound_data_chunk = FALSE;
  34.   long sound_data_offset = 0;
  35.  
  36.   fread(file_id, 4, 1, fp);
  37.   file_id[4] = '\0';
  38.   if (strcmp(file_id, "FORM") != 0)
  39.     return NULL;
  40.   
  41.   file_data_size = wave_read_int_big(fp) + 8;
  42.   
  43.   fread(form_type, 4, 1, fp);
  44.   form_type[4] = '\0';
  45.   if (strcmp(form_type, "AIFF") != 0 && strcmp(form_type, "AIFC") != 0)
  46.     return NULL;
  47.   is_aifc = strcmp(form_type, "AIFC") == 0;
  48.  
  49.   file_position = 12;
  50.   while (file_position < file_data_size)
  51.     {
  52.       char chunk_id[5];
  53.       INT chunk_data_size;
  54.  
  55.       if (fread(chunk_id, 4, 1, fp) < 1) {
  56.         if (feof(fp))
  57.           error("aiff_open: bad format: EOF encountered where chunk expected");
  58.         else if (ferror(fp))
  59.           error("aiff_open: bad format: error encountered where chunk expected: %s",
  60.                   strerror(errno));
  61.       }
  62.       chunk_id[4] = '\0';
  63.  
  64.       chunk_data_size = wave_read_int_big(fp);
  65.  
  66.       if (strcmp(chunk_id, "COMM") == 0)
  67.         /* Common chunk */
  68.         {
  69.           num_channels = wave_read_short_big(fp);
  70.           num_sample_frames = wave_read_int_big(fp);
  71.           sample_size = wave_read_short_big(fp);
  72.           sample_rate = wave_read_extended(fp);
  73.           if (is_aifc) {
  74.             fread(compression_type, 4, 1, fp);
  75.             if (feof(fp))
  76.               error("aiff_open: bad format: EOF encountered in common chunk");
  77.             compression_type[4] = '\0';
  78.           } else {
  79.             strcpy(compression_type, "NONE");
  80.           }
  81.           got_common_chunk = TRUE;
  82.         }
  83.       else if (strcmp(chunk_id, "SSND") == 0)
  84.         /* Sound Data chunk */
  85.         {
  86.           offset = wave_read_int_big(fp);
  87.           block_size = wave_read_int_big(fp);
  88.           sound_data_offset = ftell(fp) + offset;
  89.           got_sound_data_chunk = TRUE;
  90.         }
  91.  
  92.       file_position += chunk_data_size + 8;
  93.       fseek(fp, file_position, SEEK_SET);
  94.     }
  95.  
  96.   if (!got_common_chunk)
  97.     error("aiff_open: bad format: did not find common chunk");
  98.   
  99.   if (!got_sound_data_chunk)
  100.     error("aiff_open: bad format: did not find sound data chunk");
  101.  
  102.   if (strcmp(compression_type, "NONE") != 0)
  103.     error("aiff_open: bad format: compressed AIFF-C files not supported");
  104.  
  105.   fseek(fp, sound_data_offset, SEEK_SET);
  106.  
  107.   file = (tag_WAVE_FILE*)error_malloc(sizeof(WAVE_FILE));//EJT
  108.   file->is_big_endian = 1;
  109.   file->sample_offset = 0;
  110.  
  111.   info->rate = sample_rate;
  112.   info->bits = sample_size;
  113.   info->channels = num_channels;
  114.   info->length = num_sample_frames;
  115.  
  116.   return file;
  117. }
  118.  
  119. WAVE_FILE *aiff_create(FILE *fp, WAVE_INFO *info)
  120. {
  121.   BYTE bytes_per_sample;
  122.   WAVE_FILE *file;
  123.  
  124.   bytes_per_sample = (info->bits + 7) / 8;
  125.   
  126.   fwrite("FORM", 4, 1, fp);
  127.   wave_write_int_big(0xDEADBEAF, fp);
  128.   fwrite("AIFF", 4, 1, fp);
  129.  
  130.   fwrite("COMM", 4, 1, fp);
  131.   wave_write_int_big(18, fp); /* ckDataSize */
  132.   wave_write_short_big(info->channels, fp); /* numChannels */
  133.   wave_write_int_big(0xDEADBEAF, fp); /* numSampleFrames */
  134.   wave_write_short_big(info->bits, fp); /* sampleSize */
  135.   wave_write_extended(info->rate, fp); /* sampleRate */
  136.  
  137.   fwrite("SSND", 4, 1, fp);
  138.   wave_write_int_big(0xDEADBEAF, fp);
  139.   wave_write_int_big(0, fp);
  140.   wave_write_int_big(0, fp);
  141.  
  142.   file = (tag_WAVE_FILE*)error_malloc(sizeof(WAVE_FILE));//EJT
  143.   file->is_big_endian = TRUE;
  144.   file->sample_offset = 0;
  145.   return file;
  146. }
  147.  
  148. void aiff_close(WAVE_FILE *file)
  149. {
  150.   if (file->open_mode == WAVE_WRITE_MODE)
  151.     {
  152.       if (file->length % 2 == 1)
  153.         putc(0, file->fp);
  154.       
  155.       fseek(file->fp, 4, SEEK_SET);
  156.       wave_write_int_big(4 + 8 + 18 + 8 + 8 +
  157.                          file->length * ((file->bits + 7) / 8), file->fp);
  158.       fseek(file->fp, 12 + 10, SEEK_SET);
  159.       wave_write_int_big(file->length, file->fp);
  160.       fseek(file->fp, 12 + 18 + 8 + 4, SEEK_SET);
  161.       wave_write_int_big(file->length * ((file->bits + 7) / 8) + 8, file->fp);
  162.     }
  163. }
  164.